import { Observable } from 'rxjs';
import { businsessHttpServer } from './../http/http-server';
import axios from 'axios';

export abstract class Watcher {
    watcherType: string;
    timer: any;
    onTime: (sender) => any;
    invealTiming: number;
    start() {
        this.timer = setInterval(() => {
            this.timeAction();
        }, this.invealTiming);
    }
    stop() {
        clearInterval(this.timer);
    }
    timeAction() {
        return this.onTime && this.onTime(this);
    }
}



export class FBSWatcher extends Watcher {
    invealTiming = 20000;
    watcherType = "FBSWatcher";
}

export class CloundWatcher extends Watcher {
    invealTiming = 10000;
    watcherType = "CloundWatcher";
}

export class ShellWatcher extends Watcher {
    invealTiming = 500;
    watcherType = ShellWatcher.name;
}

export class AsyncWatcher extends Watcher {
    watcherType = "AsyncWatcher";
    start() {
        const xx = async () => {
            await this.timeAction();
            xx();
        }
        xx();
    }
}


export abstract class Task<T> {
    taskType: string;
    abstract selfCheck();
    destory() {

    }
    onChecked: (sender: T) => void
}

export class LDCOnlineCheckTask extends Task<boolean> {
    storeId;
    LDCHost;
    constructor(storeId, LDCHost) {
        super();
        this.storeId = storeId;
        this.LDCHost = LDCHost;
    }
    taskType = "FBSWatcher";
    async selfCheck() {
        try {
            await businsessHttpServer("/api/system/isOnline").get();
            this.onChecked && this.onChecked(true);
        } catch (error) {
            this.onChecked && this.onChecked(false);
        }
    }
}

export class CloundLDCConfigTask extends Task<any> {
    storeId;
    constructor(storeId) {
        super();
        this.storeId = storeId;
    }
    taskType = "CloundWatcher";
    async selfCheck() {
        try {
            const res = (await axios.get("/api/stores/" + this.storeId + "/config/get/config?type=system.ldc")).data;
            this.onChecked(res.data && res.data.value);
        } catch (error) {
            this.onChecked(null);
        }
    }
}

// 600-未知错误
// 601-卡片连接失败的已知异常（例如突然拿开卡片）
// 602-卡片连接失败的未知异常
// 603-读卡器连接失败
// 604-读卡时出现异常
export class CardreaderTask extends Task<{ retCode: 0 | 404 | 600 | 603 ; data?: { uid: string } }> {
    errorTip = {
        404: "读卡接口有误",
        600: "未知错误",
        603: "读卡器连接失败",
    }

    constructor() {
        super();
        this.selfCheck();
    }
    taskType = "AsyncWatcher";
    currentDelay: 400 | 5000 = 400;
    async selfCheck() {
        const cardReadHandler = (err,data:any)=>{
            let resData = {
                retCode:0,
                data:{}
            }
            if(err){
                resData.retCode = data;
            } else {
                resData.data = {
                    uid:data
                }
            }
            console.log("err,data,resData",err,data,resData);
            this.onChecked && this.onChecked(<any>resData);
        }

        (<any>window).cardreader && (<any>window).cardreader.stopRead((err,data)=>{
            console.log("stopRead", err,data); 
            (<any>window).cardreader && (<any>window).cardreader.startRead("pc/sc","", cardReadHandler);
            (<any>window).cardreader && (<any>window).cardreader.startRead("dk","", cardReadHandler)
        })
    }
}


export class TaskManage {
    static current = new TaskManage();
    watcherList: Array<Watcher> = [];
    taskList: Array<Task<any>> = [];
    addTask(task: Task<any>) {
        this.taskList.push(task);
        this.watcherList.filter(watcher => watcher.watcherType == task.taskType).forEach(watcher => watcher.onTime = (sender) => {
            return Promise.all(this.taskList.filter(task => task.taskType == sender.watcherType).map(task => task.selfCheck()));
        })
    }
    public addWatcher(watcher: Watcher) {
        watcher.onTime = (sender: Watcher) => {
            return Promise.all(this.taskList.filter(task => task.taskType == sender.watcherType).map(task => task.selfCheck()));
        }
        this.watcherList.push(watcher);
    }

    removeTask(task: Task<any>) {

    }
}
